///////////////////////////////////////////////////////////////////////////////
// File:        CircleBuffer.inl
// Author:      671643387@qq.com
// Description: 
///////////////////////////////////////////////////////////////////////////////

template<std::size_t SIZE>
CircleBuffer<SIZE>::CircleBuffer(void)
    : size_(0)
    , rpos_(0)
    , wpos_(0)
{

}

template<std::size_t SIZE>
CircleBuffer<SIZE>::~CircleBuffer(void)
{

}

template<std::size_t SIZE>
std::size_t CircleBuffer<SIZE>::read(char* buf, std::size_t len)
{
    if (size_ == 0)
        return 0;

    std::size_t bytsCpy = std::min(size_, len);

    if (bytsCpy <= SIZE - rpos_)
    {
        memcpy(buf, &buf_[rpos_], bytsCpy);
        rpos_ += bytsCpy;
        if (rpos_ == SIZE)
            rpos_ = 0;
    }
    else
    {
        std::size_t size1 = SIZE - rpos_;
        memcpy(buf, &buf_[rpos_], size1);
        std::size_t size2 = bytsCpy - size1;
        memcpy(buf + size1, &buf_[0], size2);
        rpos_ = size2;
    }
    size_ -= bytsCpy;

    return bytsCpy;
}

template<std::size_t SIZE>
std::size_t CircleBuffer<SIZE>::peek(char* buf, std::size_t len)
{
    if (size_ == 0)
        return 0;

    std::size_t bytsCpy = std::min(size_, len);

    if (bytsCpy <= SIZE - rpos_)
    {
        memcpy(buf, &buf_[rpos_], bytsCpy);
    }
    else
    {
        std::size_t size1 = SIZE - rpos_;
        memcpy(buf, &buf_[rpos_], size1);
        std::size_t size2 = bytsCpy - size1;
        memcpy(buf + size1, &buf_[0], size2);
    }

    return bytsCpy;
}

template<std::size_t SIZE>
std::size_t CircleBuffer<SIZE>::skip(std::size_t len)
{
    if (size_ == 0)
        return 0;

    std::size_t bytsSkp = std::min(size_, len);

    if (bytsSkp <= SIZE - rpos_)
    {
        rpos_ += bytsSkp;
        if (rpos_ == SIZE)
            rpos_ = 0;
    }
    else
        rpos_ = bytsSkp - (SIZE - rpos_);

    return bytsSkp;
}

template<std::size_t SIZE>
std::size_t CircleBuffer<SIZE>::write(const char* buf, std::size_t len)
{
    if (space() == 0)
        return 0;

    std::size_t bytsWrit = std::min(space(), len);

    if (bytsWrit <= SIZE - wpos_)
    {
        memcpy(&buf_[wpos_], buf, bytsWrit);
        wpos_ += bytsWrit;
        if (wpos_ == SIZE)
            wpos_ = 0;
    }
    else
    {
        std::size_t size1 = SIZE - wpos_;
        memcpy(&buf_[wpos_], buf, size1);
        std::size_t size2 = bytsWrit - size1;
        memcpy(&buf_[0], buf + size1, size2);
        wpos_ = size2;
    }
    size_ += bytsWrit;

    return bytsWrit;
}